package com.vhall.component.controller.redpacket;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.vhall.component.controller.redpacket.facade.RedPacketFacade;
import com.vhall.component.controller.room.facade.RoomInnerFacade;
import com.vhall.component.entity.rebroadcast.RedPacketRecordEntity;
import com.vhall.component.entity.redpacket.vo.*;
import com.vhall.component.entity.room.dto.RoomsEntityDTO;
import com.vhall.component.framework.common.annotation.VhallComponent;
import com.vhall.component.framework.common.exception.BusinessException;
import com.vhall.component.plugin.common.annotation.VssTokenAuth;
import com.vhall.component.plugin.common.exception.BizErrorCode;
import com.vhall.component.plugin.common.support.VssToken;
import com.vhall.component.plugin.common.support.VssTokenThreadLocal;
import com.vhall.component.service.redpacket.common.RedpacketConstants;
import com.vhall.component.service.redpacket.service.RedPacketRecordService;
import com.vhall.component.service.redpacket.service.RedPacketRefundService;
import com.vhall.component.service.redpacket.service.RedPacketService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;

import java.util.List;

/**
 * @author yongzheng.xu
 * @date 2021/7/8 12:43
 */
@Slf4j
@VssTokenAuth
@VhallComponent
public class RedPacketController implements RedPacketFacade {

    @Autowired
    private RedPacketService redPacketService;

    @Autowired
    private RedPacketRecordService redPacketRecordService;

    @Autowired
    private RedPacketRefundService redPacketRefundService;

    @Autowired
    private RoomInnerFacade roomInnerFacade;

    @Override
    public RedPacketCreateRspVO create(RedPacketCreateReqVO vo) {
        long start = System.currentTimeMillis();
        if (RedpacketConstants.CHANNEL_WXPAY.equals(vo.getChannel())
                && RedpacketConstants.SRV_CODE_JSAPI.equals(vo.getServiceCode())
                && StringUtils.isAllEmpty(vo.getOpenId())) {
            throw new BusinessException(BizErrorCode.BIZ_INVALID_PARAM);
        }
        VssToken token = VssTokenThreadLocal.getToken();
        // giftType没有传的话，默认设为1（红包）
        if (vo.getGiftType() == null) {
            vo.setGiftType(RedpacketConstants.GIFT_RED_PACKET);
        }
        // 校验金额，不能为0；
        if (vo.getAmount() != null && RedpacketConstants.ZERO_AMOUNT.compareTo(vo.getAmount()) == 0) {
            throw new BusinessException(BizErrorCode.COMP_REDPACKET_AMOUNT_ZERO_ERROR);
        }
        // 校验金额，不能超出20000；
        if (vo.getAmount() != null && RedpacketConstants.UPPER_AMOUNT.compareTo(vo.getAmount()) < 0) {
            throw new BusinessException(BizErrorCode.COMP_REDPACKET_AMOUNT_BEYOND_ERROR);
        }
        // 校验数量，不能为0；
        if (vo.getNumber() != null && RedpacketConstants.ZERO_NUM.compareTo(vo.getNumber()) == 0) {
            throw new BusinessException(BizErrorCode.COMP_REDPACKET_NUMS_ERROR);
        }
        // 校验数量，不能超出200；
        if (vo.getNumber() != null && RedpacketConstants.UPPER_NUM.compareTo(vo.getNumber()) < 0) {
            throw new BusinessException(BizErrorCode.COMP_REDPACKET_NUMS_BEYOND_ERROR);
        }
        RedPacketCreateRspVO redPacketCreateRspVO = redPacketService.create(token, vo);
        long end = System.currentTimeMillis();
        log.info("耗费时间为：{}毫秒", end - start);
        return redPacketCreateRspVO;
    }

    @Override
    public RedPacketJoinRspVO join(@Validated RedPacketJoinVO reqVO) {
        if (reqVO.getRoomId() != null && reqVO.getRoomId().length() > 255) {
            throw new BusinessException(BizErrorCode.BIZ_INVALID_PARAM);
        }
        JSONObject unlock = new JSONObject();
        if (StringUtils.isNotEmpty(reqVO.getUnlock()) && !"[]".equals(reqVO.getUnlock())) {
            unlock = JSON.parseObject(reqVO.getUnlock());
        }
        return redPacketService.join(reqVO, unlock);
    }

    @Override
    public RedPacketGetRspVO get(RedPacketJoinVO vo) {
        JSONObject unlock = new JSONObject();
        if (StringUtils.isNotEmpty(vo.getUnlock()) && !"[]".equals(vo.getUnlock())) {
            unlock = JSON.parseObject(vo.getUnlock());
        }
        // 从room获取房间的channelId;
        RoomsEntityDTO room = roomInnerFacade.getRoomInfo(vo.getRoomId());
        if (null == room) {
            throw new BusinessException(BizErrorCode.EMPTY_ROOM);
        }
        return redPacketService.snatch(vo, unlock, "");
    }

    @Override
    public RedPacketGetMyInfoRspVO getMyInfo(RedPacketGetMyInfoReqVO vo) {
        if (vo.getGiftType() == null) {
            vo.setGiftType(1);
        }
        return redPacketService.getMyInfo(vo);
    }

    @Override
    public RedPacketGetLastInfoRspVO getLastInfo(RedPacketGetLastInfoReqVO vo) {
        RoomsEntityDTO room = roomInnerFacade.getRoomInfo(vo.getRoomId());
        if (null == room) {
            throw new BusinessException(BizErrorCode.EMPTY_ROOM);
        }
        return redPacketService.getLastInfo(vo);
    }

    @Override
    public RedPacketGetRecordsRspVO getRecords(RedPacketGetRecordsReqVO vo) {
        return redPacketService.getRecords(vo);
    }

    @Override
    public GetListRspVO list(GetListReqVO reqVO) {
        return redPacketService.listPacket(reqVO);
    }

    @Override
    public RedPacketVO info(ReqVo reqVO) {
        return redPacketService.getInfo(reqVO);
    }

    @Override
    public RedPacketStatRspVO stat(RedPacketStatReqVO reqVO) {
        return redPacketService.getStat(reqVO);
    }

    @Override
    public RedPacketRecordEntity record(RedPacketRecordReqVO reqVO) {
        return redPacketRecordService.getRecord(reqVO);
    }

    @Override
    public RedPacketRecordsRspVO records(RedPacketRecordsReqVO req) {
        //sourceId和RedPacketId不能同时为空
        if (StringUtils.isBlank(req.getSourceId()) && StringUtils.isBlank(req.getRedPacketUuid())) {
            throw new BusinessException(BizErrorCode.BIZ_INVALID_PARAM);
        }

        // 默认金额排序
        if (StringUtils.isBlank(req.getOrder())) {
            req.setOrder("amount_ranking");
        }
        //page和page_size赋初值
        if (null == req.getPage()) {
            req.setPage(1);
        }
        if (null == req.getPageSize()) {
            req.setPageSize(10);
        }

        return redPacketRecordService.getRecords(req);
    }

    @Override
    public RedPacketVO getInfoBySourceId(OverBySourceIdReqVO reqVO) {
        return redPacketService.getInfoBySourceId(reqVO);
    }

    @Override
    public List<RedPacketVO> overBySourceId(OverBySourceIdReqVO reqVO) {
        return redPacketRefundService.overBySourceId(reqVO);
    }

    @Override
    public Boolean unlock(RedPacketUnLockReqVO reqVO) {
        return redPacketService.unLock(reqVO);
    }

}
